package com.yn.xgame.logic.handler;

import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yn.xgame.DBHandler;
import com.yn.xgame.logic.DbServer;
import com.yn.xgame.logic.player.LoginHistory;
import com.yn.xgame.logic.util.CheckUtils;
import com.yn.xgame.logic.util.DateStyle;
import com.yn.xgame.logic.util.GenUtils;
import com.yn.xgame.logic.util.MD5Utils;
import com.yn.xgame.message.C2GPbRedirectMessage;
import com.yn.xgame.pb.ClientGateProto;

public class LoginHandler extends DBHandler {
	
	private static final Logger logger = LoggerFactory.getLogger(DbServer.class);
	
	public LoginHandler(QueryRunner runner, Connection conn) {
		m_runner = runner;
		m_conn = conn;
	}
	
	@Override
	public Logger logger() {
		// TODO Auto-generated method stub
		return logger;
	}
	
	 // 处理登陆请求
    public Pair<Integer,String> login(C2GPbRedirectMessage msg) {
        ClientGateProto.Login login = msg.getPb().getLogin();
        try {
        	String clientToken=msg.getPb().getLogin().getToken();
        	if(StringUtils.isNotBlank(clientToken)){
        		Map<String, Object> latest=queryOne("select username from login_history where token=? order by id desc limit 1",new Object[]{clientToken});
        		if(latest!=null){
        			String resultUsername=getString(latest, "username");
        			if(StringUtils.isNotBlank(resultUsername)){
        				Map<String,Object> user=queryOne("select user_id from user where user_name=? limit 1", new Object[]{resultUsername});
        				Integer userId=(Integer) user.get("user_id");
        				if(userId!=null){
        					return Pair.of(-1, clientToken+","+resultUsername);
        				}
        			}
        		}
        		return Pair.of(0, null);
        	}
        	String username = login.getUsername();
            if (!CheckUtils.checkUserName(username)) { //帐号格式不正确
                return Pair.of(4, null);
            }
            if (userIsLocked(username)) { //帐号被锁
                return Pair.of(3, null);
            }
            String sql = "select user_pwd from user where user_name = ?";
            Map<String, Object> result = queryOne(sql, new Object[]{username});
            if (result == null) {// 账号不存在
                return Pair.of(4, null);
            }
            if (!getString(result, "user_pwd").equals(MD5Utils.encryptTohex(login.getPassword()))) { //密码错误
                saveLoginHistory(username, "0", null, null);
                return Pair.of(2, null);
            }
            String token=GenUtils.genUserToken(username);
            saveLoginHistory(username,"1",token,1);
            return Pair.of(1, token);
        } catch (Exception e) {
            logger.error("error: ", e);
            if (e instanceof SQLException) { //数据库异常
                return Pair.of(5, null);
            }
        }
        return Pair.of(6, null);
    }

    private boolean userIsLocked(String username) throws SQLException {
        String sql = "select * from login_history where username=? and failed_count=3 order by id desc limit 1";
        Map<String, Object> result = queryOne(sql, new Object[]{username});
        if (result == null) {
            return false;
        }
        long interval = System.currentTimeMillis() - getTimeLong(result, "login_time");
        if (interval > 15 * 60 * 1000) {
            return false;
        }
        return true;
    }
    
    /**
     * 保存登录历史
     * @param username
     * @param success
     * @param token
     * @param type
     * @return
     * @throws SQLException
     */
    private boolean saveLoginHistory(String username, String success,String token, Integer type) throws SQLException{
    	int failedCount=0;
    	Calendar cal=Calendar.getInstance();
    	if("0".equals(success)){
    		failedCount++;
    		cal.add(Calendar.MINUTE, -1);
			SimpleDateFormat sdf=new SimpleDateFormat(DateStyle.YYYY_MM_DD_HH_MM_SS.getValue());
			String beginTime=sdf.format(cal.getTime());
			String sql1="select * from login_history where username=? and login_time>'"+beginTime+ "' order by id desc";
			List<LoginHistory> loginedList=queryList(sql1, LoginHistory.class, new Object[]{username});
			if(loginedList!=null&&!loginedList.isEmpty()){
				if("0".equals(loginedList.get(0).getSuccess())){
					failedCount++;
					if(loginedList.size()>1){
						if("0".equals(loginedList.get(1).getSuccess())){
							failedCount++;
						}
					}
				}
			}
    	}
    	LoginHistory logined=new LoginHistory();
		if(StringUtils.isNotBlank(token)){
			logined.setToken(token);
		}
		if(type!=null){
			logined.setType(type);
		}
		logined.setUsername(username);
		logined.setSuccess(success);
		logined.setFailedCount(failedCount);
		String sql2="insert into login_history(username,success,failed_count,token,type) values(?,?,?,?,?)";
    	if(saveUpdate(sql2, new Object[]{username,success,failedCount,token,type})>0){
    		return true;
    	}
    	return false;
    }
    
}
